/*
 * MIT License
 *
 * Copyright (c) 2023 北京凯特伟业科技有限公司
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
package com.je.document.rpc;

import cn.hutool.core.io.FileUtil;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.je.common.base.document.FileBound;
import com.je.common.base.document.FileCopyDTO;
import com.je.common.base.document.InternalFileBO;
import com.je.common.base.document.InternalFileUpload;
import com.je.common.base.service.rpc.DocumentInternalRpcService;
import com.je.common.base.util.StringUtil;
import com.je.document.model.FileBO;
import com.je.document.model.FileUpload;
import com.je.document.service.DocumentBusService;
import com.je.document.service.DocumentService;
import org.apache.servicecomb.provider.pojo.RpcSchema;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import java.io.File;
import java.util.ArrayList;
import java.util.List;

@RpcSchema(schemaId = "documentInternalRpcService")
public class DocumentInternalRpcServiceImpl implements DocumentInternalRpcService {

    @Autowired
    private DocumentBusService documentBusService;
    @Autowired
    private Environment environment;

    @Autowired
    private DocumentService documentService;

    @Override
    public InternalFileBO saveSingleFile(InternalFileUpload fileUploadFile, File file, String userId) {
        FileUpload upload = new FileUpload(fileUploadFile.getFileKey(),fileUploadFile.getFileName(),fileUploadFile.getContentType(),fileUploadFile.getSize(), FileUtil.getInputStream(file));
        FileBO fileBO = documentBusService.saveSingleFile(upload, userId);
        InternalFileBO internalFileBO = new InternalFileBO();
        BeanUtils.copyProperties(fileBO,internalFileBO);
        return internalFileBO;
    }

    @Override
    public InternalFileBO saveSingleFileWithMetadata(InternalFileUpload fileUploadFile, File file, String userId, JSONObject metadata) {
        FileUpload upload = new FileUpload(fileUploadFile.getFileKey(),fileUploadFile.getFileName(),fileUploadFile.getContentType(),
                fileUploadFile.getSize(), FileUtil.getInputStream(file));
        FileBO fileBO = documentBusService.saveSingleFile(upload,userId,metadata);
        InternalFileBO internalFileBO = new InternalFileBO();
        BeanUtils.copyProperties(fileBO,internalFileBO);
        return internalFileBO;
    }

    @Override
    public InternalFileBO saveSingleFileWithBucket(InternalFileUpload fileUploadFile, File file, String userId, String bucket) {
        FileUpload upload = new FileUpload(fileUploadFile.getFileKey(),fileUploadFile.getFileName(),fileUploadFile.getContentType(),
                fileUploadFile.getSize(), FileUtil.getInputStream(file));
        FileBO fileBO = documentBusService.saveSingleFile(upload,userId,bucket);
        InternalFileBO internalFileBO = new InternalFileBO();
        BeanUtils.copyProperties(fileBO,internalFileBO);
        return internalFileBO;
    }

    @Override
    public InternalFileBO saveSingleFileWithMetadataAndBucket(InternalFileUpload fileUploadFile, File file, String userId,
                                                              JSONObject metadata, String bucket) {
        FileUpload upload = new FileUpload(fileUploadFile.getFileKey(),fileUploadFile.getFileName(),fileUploadFile.getContentType(),
                fileUploadFile.getSize(), FileUtil.getInputStream(file));
        FileBO fileBO = documentBusService.saveSingleFile(upload,userId,metadata,bucket);
        InternalFileBO internalFileBO = new InternalFileBO();
        BeanUtils.copyProperties(fileBO,internalFileBO);
        return internalFileBO;
    }

    @Override
    public List<InternalFileBO> saveMultiFile(List<InternalFileUpload> fileUploadFiles, List<File> files, String userId) {
        List<InternalFileBO> internalFileBOS = new ArrayList<>();
        FileUpload eachFileUpload;
        InternalFileBO internalFileBO;
        FileBO fileBO;
        for (int i = 0; i < fileUploadFiles.size(); i++) {
            eachFileUpload = new FileUpload(fileUploadFiles.get(i).getFileKey(),fileUploadFiles.get(i).getFileName(),
                    fileUploadFiles.get(i).getContentType(),
                    fileUploadFiles.get(i).getSize(), FileUtil.getInputStream(files.get(i)));
            fileBO = documentBusService.saveSingleFile(eachFileUpload,userId);
            internalFileBO = new InternalFileBO();
            BeanUtils.copyProperties(fileBO,internalFileBO);
            internalFileBOS.add(internalFileBO);
        }
        return internalFileBOS;
    }

    @Override
    public List<InternalFileBO> saveMultiFileWithMetadata(List<InternalFileUpload> fileUploadFiles, List<File> files, String userId, JSONObject metadata) {
        List<InternalFileBO> internalFileBOS = new ArrayList<>();
        FileUpload eachFileUpload;
        InternalFileBO internalFileBO;
        FileBO fileBO;
        for (int i = 0; i < fileUploadFiles.size(); i++) {
            eachFileUpload = new FileUpload(fileUploadFiles.get(i).getFileKey(),fileUploadFiles.get(i).getFileName(),
                    fileUploadFiles.get(i).getContentType(),
                    fileUploadFiles.get(i).getSize(), FileUtil.getInputStream(files.get(i)));
            fileBO = documentBusService.saveSingleFile(eachFileUpload,userId,metadata);
            internalFileBO = new InternalFileBO();
            BeanUtils.copyProperties(fileBO,internalFileBO);
            internalFileBOS.add(internalFileBO);
        }
        return internalFileBOS;
    }

    @Override
    public List<InternalFileBO> saveMultiFileWithBucket(List<InternalFileUpload> fileUploadFiles, List<File> files, String userId, String bucket) {
        List<InternalFileBO> internalFileBOS = new ArrayList<>();
        FileUpload eachFileUpload;
        InternalFileBO internalFileBO;
        FileBO fileBO;
        for (int i = 0; i < fileUploadFiles.size(); i++) {
            eachFileUpload = new FileUpload(fileUploadFiles.get(i).getFileKey(),fileUploadFiles.get(i).getFileName(),
                    fileUploadFiles.get(i).getContentType(),
                    fileUploadFiles.get(i).getSize(), FileUtil.getInputStream(files.get(i)));
            fileBO = documentBusService.saveSingleFile(eachFileUpload,userId,bucket);
            internalFileBO = new InternalFileBO();
            BeanUtils.copyProperties(fileBO,internalFileBO);
            internalFileBOS.add(internalFileBO);
        }
        return internalFileBOS;
    }

    @Override
    public List<InternalFileBO> saveMultiFileWithMetadataAndBucket(List<InternalFileUpload> fileUploadFiles, List<File> files, String userId, JSONObject metadata, String bucket) {
        List<InternalFileBO> internalFileBOS = new ArrayList<>();
        FileUpload eachFileUpload;
        InternalFileBO internalFileBO;
        FileBO fileBO;
        for (int i = 0; i < fileUploadFiles.size(); i++) {
            eachFileUpload = new FileUpload(fileUploadFiles.get(i).getFileKey(),fileUploadFiles.get(i).getFileName(),
                    fileUploadFiles.get(i).getContentType(),
                    fileUploadFiles.get(i).getSize(), FileUtil.getInputStream(files.get(i)));
            fileBO = documentBusService.saveSingleFile(eachFileUpload,userId,metadata,bucket);
            internalFileBO = new InternalFileBO();
            BeanUtils.copyProperties(fileBO,internalFileBO);
            internalFileBOS.add(internalFileBO);
        }
        return internalFileBOS;
    }

    @Override
    public List<InternalFileBO> saveMultiFileWithMetadataAndBucketToDestDir(List<InternalFileUpload> fileUploadFiles, List<File> files, String userId, JSONObject metadata, String bucket, String dir) {
        FileUpload eachFileUpload;
        List<FileUpload> uploadList = new ArrayList<>();
        for (int i = 0; i < fileUploadFiles.size(); i++) {
            eachFileUpload = new FileUpload(fileUploadFiles.get(i).getFileKey(),fileUploadFiles.get(i).getFileName(),
                    fileUploadFiles.get(i).getContentType(),
                    fileUploadFiles.get(i).getSize(), FileUtil.getInputStream(files.get(i)));
            uploadList.add(eachFileUpload);
        }
        List<InternalFileBO> internalFileBOS = new ArrayList<>();
        List<FileBO> fileBOList = documentBusService.saveFile(uploadList,userId,metadata,bucket,dir);
        InternalFileBO eachInternalFileBo;
        for (FileBO eachFileBo : fileBOList) {
            eachInternalFileBo = new InternalFileBO();
            BeanUtils.copyProperties(eachFileBo,eachInternalFileBo);
            internalFileBOS.add(eachInternalFileBo);
        }
        return internalFileBOS;
    }

    @Override
    public InternalFileBO boundSingleFile(FileBound fileBoundFile, String userId, JSONObject metadata, String bucket) {
        FileBO fileBO = documentBusService.boundSingleFile(fileBoundFile,userId,metadata,bucket);
        InternalFileBO internalFileBO = new InternalFileBO();
        BeanUtils.copyProperties(fileBO,internalFileBO);
        return internalFileBO;
    }

    @Override
    public List<InternalFileBO> boundFile(List<FileBound> fileBounds, String userId, JSONObject metadata, String bucket) {
        List<FileBO> fileBOList = documentBusService.boundFile(fileBounds,userId,metadata,bucket);
        List<InternalFileBO> internalFileBOS = new ArrayList<>();
        InternalFileBO eachInternalFileBo;
        for (FileBO eachFileBo : fileBOList) {
            eachInternalFileBo = new InternalFileBO();
            BeanUtils.copyProperties(eachFileBo,eachInternalFileBo);
            internalFileBOS.add(eachInternalFileBo);
        }
        return internalFileBOS;
    }

    @Override
    public void saveFileMetadataWithFileKeys(String userId, JSONObject metadata, List<String> fileKeys) {
        documentBusService.saveFileMetadata(userId,metadata,fileKeys);
    }

    @Override
    public void saveFileMetadataWithRelIdAndFileId(String userId, JSONObject metadata, String relId, String fileId) {
        documentBusService.saveFileMetadata(userId,metadata,relId,fileId);
    }

    @Override
    public void updateMetadataByKey(String fileKey, String newRelName, JSONObject metadata, String userId) {
        documentBusService.updateMetadataByKey(fileKey,newRelName,metadata,userId);
    }

    @Override
    public JSONObject selectFileMetadataByKey(String fileKey) {
        return documentBusService.selectFileMetadataByKey(fileKey);
    }

    @Override
    public InternalFileBO editByFileKey(String fileKey, File file, String userId) {
        FileBO fileBO = documentBusService.editByFileKey(fileKey,FileUtil.getInputStream(file),userId);
        InternalFileBO internalFileBO = new InternalFileBO();
        BeanUtils.copyProperties(fileBO,internalFileBO);
        return internalFileBO;
    }

    @Override
    public InternalFileBO copyRelByKey(String fileKey, String newRelName, JSONObject metadata, String userId) {
        FileBO fileBO = documentBusService.copyRelByKey(fileKey,newRelName,metadata,userId);
        InternalFileBO internalFileBO = new InternalFileBO();
        BeanUtils.copyProperties(fileBO,internalFileBO);
        return internalFileBO;
    }

    @Override
    public void delFilesByKey(List<String> fileKeys, String userId) {
        documentBusService.delFilesByKey(fileKeys,userId);
    }

    @Override
    public boolean exists(String fileKey) {
        return documentBusService.exists(fileKey);
    }

    @Override
    public InternalFileBO selectFileByKey(String fileKey) {
        FileBO fileBO = documentBusService.selectFileByKey(fileKey);
        InternalFileBO internalFileBO = new InternalFileBO();
        BeanUtils.copyProperties(fileBO,internalFileBO);
        return internalFileBO;
    }

    @Override
    public InternalFileBO selectFileByKeyAndVersion(String fileKey, String version) {
        FileBO fileBO = documentBusService.selectFileByKeyAndVersion(fileKey, version);
        InternalFileBO internalFileBO = new InternalFileBO();
        BeanUtils.copyProperties(fileBO,internalFileBO);
        return internalFileBO;
    }

    @Override
    public List<InternalFileBO> selectFileListByKey(List<String> keys) {
        List<FileBO> fileBOList = documentBusService.selectFileListByKey(keys);
        List<InternalFileBO> internalFileBOS = new ArrayList<>();
        InternalFileBO eachInternalFileBo;
        for (FileBO eachFileBo : fileBOList) {
            eachInternalFileBo = new InternalFileBO();
            BeanUtils.copyProperties(eachFileBo,eachInternalFileBo);
            internalFileBOS.add(eachInternalFileBo);
        }
        return internalFileBOS;
    }

    @Override
    public List<InternalFileBO> selectFileByMetadata(JSONObject metadataQuery) {
        List<FileBO> fileBOList = documentBusService.selectFileByMetadata(metadataQuery);
        List<InternalFileBO> internalFileBOS = new ArrayList<>();
        InternalFileBO eachInternalFileBo;
        for (FileBO eachFileBo : fileBOList) {
            eachInternalFileBo = new InternalFileBO();
            BeanUtils.copyProperties(eachFileBo,eachInternalFileBo);
            internalFileBOS.add(eachInternalFileBo);
        }
        return internalFileBOS;
    }

    @Override
    public List<InternalFileBO> selectFileFullByMetadata(JSONObject metadataQuery) {
        List<FileBO> fileBOList = documentBusService.selectFileFullByMetadata(metadataQuery);
        List<InternalFileBO> internalFileBOS = new ArrayList<>();
        InternalFileBO eachInternalFileBo;
        for (FileBO eachFileBo : fileBOList) {
            eachInternalFileBo = new InternalFileBO();
            BeanUtils.copyProperties(eachFileBo,eachInternalFileBo);
            internalFileBOS.add(eachInternalFileBo);
        }
        return internalFileBOS;
    }

    @Override
    public File readFile(String fileKey) {
        FileBO fileBO = documentBusService.readFile(fileKey);
        String tempDir = environment.getProperty("servicecomb.downloads.directory");
        if(!FileUtil.exist(tempDir)){
            FileUtil.mkdir(tempDir);
        }
        String suffix=getFileTypeSuffix(fileBO.getRelName());
        return FileUtil.writeFromStream(fileBO.getFile(),tempDir + File.separator + "."+suffix);
    }
    public String getFileTypeSuffix(String filePath){
        String fileType="";
        if(StringUtil.isNotEmpty(filePath)){
            int lastIndex=filePath.lastIndexOf(".");
            if(lastIndex!=-1){
                fileType=filePath.substring(lastIndex+1);
            }
        }
        return fileType;
    }
    @Override
    public List<InternalFileBO> selectAllVersionFiles(String fikeKey) {
        List<FileBO> fileBOList = documentBusService.selectAllVersionFiles(fikeKey);
        List<InternalFileBO> internalFileBOS = new ArrayList<>();
        InternalFileBO eachInternalFileBo;
        for (FileBO eachFileBo : fileBOList) {
            eachInternalFileBo = new InternalFileBO();
            BeanUtils.copyProperties(eachFileBo,eachInternalFileBo);
            internalFileBOS.add(eachInternalFileBo);
        }
        return internalFileBOS;
    }

    @Override
    public InternalFileBO selectVersionFile(String fikeKey, int version) {
        FileBO fileBO = documentBusService.selectVersionFile(fikeKey, version);
        InternalFileBO internalFileBO = new InternalFileBO();
        BeanUtils.copyProperties(fileBO,internalFileBO);
        return internalFileBO;
    }

    @Override
    public void updateFiledFile(String userId, String tableCode, String pkValue, String fieldCode, List<String> usedFileKey) {
        documentBusService.updateFiledFile(userId,tableCode,pkValue,fieldCode,usedFileKey);
    }

    @Override
    public List<FileCopyDTO> copyFiles(String userId, String tableCode, String pkValue, String fieldCode, String newPkValue) {
        return documentBusService.copyFiles(userId,tableCode,pkValue,fieldCode,newPkValue);
    }

    @Override
    public List<FileCopyDTO> copyFilesWithFuncCode(String userId, String tableCode, String pkValue, String fieldCode, String newPkValue, String newFuncCode, String newTableCode, String newFiledCode) {
        return null;
    }

    @Override
    public void deleteFiles(String tableCode, String pkValues, String userId) {
        documentBusService.deleteFiles(tableCode,pkValues,userId);
    }

    @Override
    public void deleteFilesWithFieldCodes(String tableCode, String pkValues, String fieldCodes, String userId) {
        documentBusService.deleteFiles(tableCode,pkValues,fieldCodes,userId);
    }

    @Override
    public void deleteFilesWithFieldCodesAndUploadTypes(String tableCode, String pkValues, String fieldCodes, String uploadTypes, String userId) {
        documentBusService.deleteFiles(tableCode,pkValues,fieldCodes,uploadTypes,userId);
    }

    @Override
    public JSONArray listFilesMeta(String bucket, String path) {
        return documentBusService.listFilesMeta(bucket,path);
    }

    @Override
    public File readThumbnail(String fileKey) {
        return null;
    }

    @Override
    public void deleteByFileKeys(List<String> fileKeys, String userId) {
        documentBusService.deleteByFileKeys(fileKeys, userId);
    }

}
